package com.yangming.common.redis;

import java.lang.reflect.Method;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
@EnableCaching
public class RedisCatchConfig extends CachingConfigurerSupport{
	
	    /** 
	    * 生产key的策略 
	    *  
	    * @return 
	    */  
	   @Bean  
	   @Override  
	   public KeyGenerator keyGenerator() {  
	       return new KeyGenerator() {  
	 
	           @Override  
	           public Object generate(Object target, Method method, Object... params) {  
	               StringBuilder sb = new StringBuilder();  
	               sb.append(target.getClass().getName());  
	               sb.append(method.getName());  
	               for (Object obj : params) {  
	                   sb.append(obj.toString());  
	               }  
	               return sb.toString();  
	           }  
	       };  
	   }


	   /**
	    * 管理缓存
	    * @param factory
	    * @return
	    */
	   @Bean
	   public CacheManager cacheManager(RedisConnectionFactory factory) {
		   RedisCacheManager cacheManager = RedisCacheManager.create(factory);
		   return cacheManager;
	   }

	   /** 
	    * redisTemplate配置 
	    * @param connectionFactory
	    * @return 
	    */  
	   @Bean
       public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
          RedisTemplate<Object, Object> template = new RedisTemplate<>();
          template.setConnectionFactory(connectionFactory);

          //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
          Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

          ObjectMapper mapper = new ObjectMapper();
          mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
          mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
          serializer.setObjectMapper(mapper);
         
          template.setValueSerializer(serializer);
          //使用StringRedisSerializer来序列化和反序列化redis的key值
          template.setKeySerializer(new StringRedisSerializer());
          template.afterPropertiesSet();
          return template;
       }
	
	
}
